#import "NSHTTPCookieStorage+Utils.h"
#import <objc/runtime.h>
#define HTTPCookieStrorageCustomCookies @"HTTPCookieStrorageCustomCookies"
static inline void class_methodSwizzling(Class class, SEL originalSelector, SEL swizzledSelector) {
    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
    BOOL didAddMethod = class_addMethod(class,
                                        originalSelector,
                                        method_getImplementation(swizzledMethod),
                                        method_getTypeEncoding(swizzledMethod));
    if (didAddMethod) {
        class_replaceMethod(class,
                            swizzledSelector,
                            method_getImplementation(originalMethod),
                            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}


@implementation NSHTTPCookieStorage (Utils)
+ (void)addCustomCookieValue:(id)value forKey:(NSString *)key {
    NSMutableArray *customCookies = [[NSUserDefaults standardUserDefaults] arrayForKey:HTTPCookieStrorageCustomCookies].mutableCopy;
    if (!customCookies) customCookies = [NSMutableArray array];
    BOOL is_exsit = NO;
    for (NSInteger i = 0; i < customCookies.count; i++) {
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:customCookies[i]];
        if ([dic[@"cookie_name"] isEqualToString:key]) {
            dic[@"cookie_value"] = value;
            [customCookies replaceObjectAtIndex:i withObject:dic];
            is_exsit = YES;
            break;
        }
    }
    if (!is_exsit) {
        [customCookies addObject:@{@"cookie_name": key, @"cookie_value": value}.mutableCopy];
    }
    [[NSUserDefaults standardUserDefaults] setValue:customCookies forKey:HTTPCookieStrorageCustomCookies];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
+ (void)deleteCustomCookieForKey:(NSString *)key {
    NSMutableArray *customCookies = [[NSUserDefaults standardUserDefaults] arrayForKey:HTTPCookieStrorageCustomCookies].mutableCopy;
    if (customCookies.count > 0) {
        for (NSInteger i = 0; i < customCookies.count; i++) {
            NSMutableDictionary *dic = customCookies[i];
            if ([dic[@"cookie_name"] isEqualToString:key]) {
                [customCookies removeObjectAtIndex:i];
            }
        }
    }
    [[NSUserDefaults standardUserDefaults] setValue:customCookies forKey:HTTPCookieStrorageCustomCookies];
    [[NSUserDefaults standardUserDefaults] synchronize];
}
+ (void)load {
    class_methodSwizzling(self, @selector(cookies), @selector(yf_cookies));
}
- (NSArray<NSHTTPCookie *> *)yf_cookies {
    NSArray *customCookies = [[NSUserDefaults standardUserDefaults] arrayForKey:HTTPCookieStrorageCustomCookies];
    NSMutableArray *cookies = [self yf_cookies].mutableCopy;
    for (NSDictionary *dic in customCookies) {
        BOOL is_exist = NO;
        for (NSInteger i = 0; i < cookies.count; i++) {
            NSHTTPCookie *cookie = cookies[i];
            if ([cookie.name isEqualToString:dic[@"cookie_name"]]) {
                NSHTTPCookie *new_cookie =
                    [NSHTTPCookie cookieWithProperties:@{
                        NSHTTPCookieName: cookie.name,
                        NSHTTPCookieValue: dic[@"cookie_value"],
                        NSHTTPCookieDomain: @".",
                        NSHTTPCookiePath: @"/",
                    }];
                if (new_cookie) {
                    [cookies replaceObjectAtIndex:i withObject:new_cookie];
                }
                is_exist = YES;
                break;
            }
        }
        if (!is_exist) {
            NSHTTPCookie *new_cookie =
                [NSHTTPCookie cookieWithProperties:@{NSHTTPCookieName: dic[@"cookie_name"],
                                                     NSHTTPCookieValue: dic[@"cookie_value"],
                                                     NSHTTPCookieDomain: @".",
                                                     NSHTTPCookiePath: @"/"}];
            if (new_cookie) [cookies addObject:new_cookie];
        }
    }
    return cookies.copy;
}
@end
